import { Component, OnInit } from '@angular/core'
import { AbstractControl, FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms'
import { Store } from '@ngrx/store'
import { Observable } from 'rxjs/Observable'

import * as fromRoot from '../../core/reducers'
import * as fromUserAction from '../../core/actions/user'

@Component({
  selector: 'app-login',
  templateUrl: './login.component.html',
  styleUrls: ['./login.component.less']
})
export class LoginComponent implements OnInit {
  isLoginForm: boolean
  loginForm: FormGroup
  registerForm: FormGroup
  isModelVisible = false

  isRegistered$: Observable<boolean>

  constructor (
    private _fb: FormBuilder,
    private _store: Store<fromRoot.IState>) {
    this.isRegistered$ = _store.select(fromRoot.selectIsRegistered)
  }

  ngOnInit () {
    this.loginForm = this._fb.group({
      username: [null, [Validators.required, Validators.minLength(3), Validators.pattern('[a-zA-Z]\\w+')]],
      password: [null, [Validators.required, Validators.minLength(6)]]
    })
    this.registerForm = this._fb.group({
      // ? Validators.nullValidator how to use
      username: [null, [Validators.required, Validators.minLength(3), Validators.pattern('[a-zA-Z]\\w+')]],
      password: [null, [Validators.required, Validators.minLength(6)]],
      email: [null, [Validators.required, Validators.email]]
    })

    // 监听是否注册成功
    this.isRegistered$.subscribe((is) => {
      if (is) {
        this.handleCancel()
        this.handleLogin()
      }
    })
  }

  //#region: get error message...
  public getUsernameErrorMessageForLogin (): string {
    const control = this.loginForm.controls.username
    if (control.hasError('required')) {
      return ' - 请输入用户名'
    }
    if (control.hasError('minlength')) {
      return ' - 至少需要3个字符'
    }
    if (control.hasError('pattern')) {
      return ' - 用户名必须由字母开头且只包含字母、数字和下划线'
    }
  }

  public getPasswordErrorMessageForLogin (): string {
    const control = this.loginForm.controls.password
    if (control.hasError('required')) {
      return ' - 请输入密码'
    }
    if (control.hasError('minlength')) {
      return ' - 至少需要6个字符'
    }
  }

  public getUsernameErrorMessageForRegister (): string {
    const control = this.registerForm.controls.username
    if (control.hasError('required')) {
      return ' - 请输入用户名'
    }
    if (control.hasError('minlength')) {
      return ' - 至少需要3个字符'
    }
    if (control.hasError('pattern')) {
      return ' - 用户名必须由字母开头且只包含字母、数字和下划线'
    }
  }

  public getPasswordErrorMessageForRegister (): string {
    const control = this.registerForm.controls.password
    if (control.hasError('required')) {
      return ' - 请输入密码'
    }
    if (control.hasError('minlength')) {
      return ' - 至少需要6个字符'
    }
  }

  public getEmailErrorMessageForRegister (): string {
    const control = this.registerForm.controls.email
    const { required, email } = control.errors
    if (control.hasError('required')) {
      return ' - 请输入邮箱'
    }
    if (control.hasError('email')) {
      return ' - 请输入正确的邮箱'
    }
  }
  //#endregion

  public handleLogin (): void {
    this.isModelVisible = true
    this.isLoginForm = true
  }

  public handleRegister (): void {
    this.isModelVisible = true
    this.isLoginForm = false
  }

  public handleCancel (): void {
    this.isModelVisible = false
    this.resetForms()
  }

  public resetForms (): void {
    this.loginForm.reset()
    this.registerForm.reset()
  }

  // 获取LoginForm的控件实例
  public getloginFormControl (name): AbstractControl {
    return this.loginForm.controls[name]
  }
  // LoginForm控件是否已经合法（检查之后）
  public getLoginFormControlInvalid (controlName: string): boolean {
    const control = this.getloginFormControl(controlName)
    return control.dirty && control.invalid ? true : false
  }
  // 获取RegisterForm的控件实例
  public getRegisterFormControl (name): AbstractControl {
    return this.registerForm.controls[name]
  }
  // RegisterForm控件是否已经合法（检查之后）
  public getRegisterFormControlInvalid (controlName: string): boolean {
    const control = this.getRegisterFormControl(controlName)
    return control.dirty && control.invalid ? true : false
  }

  public onSubmit (isLoginForm: boolean): void {
    if (isLoginForm) {

      const controls = this.loginForm.controls
      for (const i of Object.keys(controls)) {
        controls[i].markAsDirty()
      }
      if (this.loginForm.valid) {
        this._store.dispatch(new fromUserAction.LoginAction(this.loginForm.value))
      }

    } else {
      const controls = this.registerForm.controls
      for (const i of Object.keys(this.registerForm.controls)) {
        controls[i].markAsDirty()
      }
      if (this.registerForm.valid) {
        this._store.dispatch(new fromUserAction.RegisterAction(this.registerForm.value))
      }
    }
  }
}
